/*
 * ikakeibo 0.6.0
 * Copyright (C)2009 wateray and contributors
 * wateray@gmail.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package com.wateray.ipassbook.ui.view.contentPanel;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import org.apache.log4j.Logger;

import com.wateray.ipassbook.commom.Constant;
import com.wateray.ipassbook.domain.Entity;
import com.wateray.ipassbook.domain.Receipt;
import com.wateray.ipassbook.domain.form.ReceiptForm;
import com.wateray.ipassbook.kernel.event.IPassbookEvent;
import com.wateray.ipassbook.kernel.service.ReceiptService;
import com.wateray.ipassbook.kernel.service.SubjectService;
import com.wateray.ipassbook.ui.action.ActionManager;
import com.wateray.ipassbook.ui.action.ReceiptCopyAction;
import com.wateray.ipassbook.ui.action.ReceiptPasteAction;
import com.wateray.ipassbook.ui.action.ShowAddReceiptAction;
import com.wateray.ipassbook.ui.action.ShowAllRecorderAction;
import com.wateray.ipassbook.ui.action.ShowCurrentMonthRecordAction;
import com.wateray.ipassbook.ui.action.ShowCurrentYearRecordAction;
import com.wateray.ipassbook.ui.action.ShowDeleteReceiptAction;
import com.wateray.ipassbook.ui.action.ShowModifyReceiptAction;
import com.wateray.ipassbook.ui.action.ShowTodayRecordAction;
import com.wateray.ipassbook.ui.model.AbstractPassbookTableModel;
import com.wateray.ipassbook.ui.model.MemoReceiptTableCellRenderer;
import com.wateray.ipassbook.ui.model.PassbookComboBoxModel;
import com.wateray.ipassbook.ui.model.ReceiptTabelModel;
import com.wateray.ipassbook.ui.model.SubjectListCellRender;
import com.wateray.ipassbook.ui.widget.PassbookTable;
import com.wateray.ipassbook.ui.widget.PopUpButton;
import com.wateray.ipassbook.util.CalendarUtils;
import com.wateray.ipassbook.util.ImageManager;
import com.wateray.ipassbook.util.LanguageLoader;
import com.wateray.ipassbook.util.log4j.Log;

/**
 * @author wateray
 * @create 2009-4-30
 */
public class ReceiptPage extends AbstractPage {

	/** serialVersionUID. */
	private static final long serialVersionUID = -6234121444094837341L;

	private static ReceiptPage thisCardPanel = new ReceiptPage();
	private Logger logger = Log.getLogger(this.getClass());

	/** The addButton. */
	private JButton addButton;

	/** The modifyButton. */
	private JButton modifyButton;

	/** The deleteButton. */
	private JButton deleteButton;

	/** The dataFilterButton. */
	private PopUpButton dataFilterButton;

	/** dataFilterButton Group */
	private ButtonGroup dataFilterGroup;

	/** Button to show all records. */
	private JRadioButtonMenuItem allMenuItem;

	/** Button to show today's records. */
	private JRadioButtonMenuItem todayMenuItem;

	/** Button to show this month's records. */
	private JRadioButtonMenuItem monthMenuItem;

	/** Button to show this year's records. */
	private JRadioButtonMenuItem yearMenuItem;

	/** incomeExpress Table */
	private JTable receiptTable;

	/** the Constructor */
	private ReceiptPage() {
		super();
	}

	/**
	 * @return an instance of the ReceiptPage.
	 * */
	public static ReceiptPage getInstance() {
		if (thisCardPanel == null) {
			thisCardPanel = new ReceiptPage();
		}
		return thisCardPanel;
	}

	@Override
	protected Component getTopPane() {
		super.getTopPane();
		buttonBar.add(getAddButton());
		buttonBar.add(getModifyButton());
		buttonBar.add(getDeleteButton());
		buttonBar.add(getDataFilterButton());
		return buttonBar;
	}

	@Override
	protected Component getCenterPane() {
		return new JScrollPane(getReceiptTable());
	}

	private JButton getAddButton() {
		if (addButton == null) {
			addButton = new JButton(ActionManager
					.getAction(ShowAddReceiptAction.class));
		}
		return addButton;
	}

	private JButton getModifyButton() {
		if (modifyButton == null) {
			modifyButton = new JButton(ActionManager
					.getAction(ShowModifyReceiptAction.class));
			// modifyButton.setText(LanguageLoader
			// .getString("Modify"));
		}
		return modifyButton;
	}

	private JButton getDeleteButton() {
		if (deleteButton == null) {
			deleteButton = new JButton(ActionManager
					.getAction(ShowDeleteReceiptAction.class));
			// deleteButton.setText(LanguageLoader
			// .getString("Delete"));
		}
		return deleteButton;
	}

	private JButton getDataFilterButton() {
		if (dataFilterButton == null) {
			dataFilterButton = new PopUpButton(LanguageLoader
					.getString("Data_Filter"), PopUpButton.BOTTOM_RIGHT);

			allMenuItem = new JRadioButtonMenuItem(ActionManager
					.getAction(ShowAllRecorderAction.class));
			todayMenuItem = new JRadioButtonMenuItem(ActionManager
					.getAction(ShowTodayRecordAction.class));
			monthMenuItem = new JRadioButtonMenuItem(ActionManager
					.getAction(ShowCurrentMonthRecordAction.class));
			yearMenuItem = new JRadioButtonMenuItem(ActionManager
					.getAction(ShowCurrentYearRecordAction.class));

			dataFilterGroup = new ButtonGroup();
			dataFilterGroup.add(allMenuItem);
			dataFilterGroup.add(todayMenuItem);
			dataFilterGroup.add(monthMenuItem);
			dataFilterGroup.add(yearMenuItem);

			dataFilterButton.add(allMenuItem);
			dataFilterButton.add(new JSeparator());
			dataFilterButton.add(todayMenuItem);
			dataFilterButton.add(monthMenuItem);
			dataFilterButton.add(yearMenuItem);
			dataFilterButton.add(new JSeparator());

			allMenuItem.setSelected(true);
			showData(CalendarUtils.getInstance());

		}
		return dataFilterButton;
	}

	/**
	 * @return receiptTable
	 * */
	public JTable getReceiptTable() {
		if (receiptTable == null) {
			// receiptTable = new JTable();
			receiptTable = new ReceiptTable(); // UPD 2009/06/05
			ReceiptTabelModel dataModel = new ReceiptTabelModel(
					getColumnNames());
			receiptTable.setModel(dataModel);

			setCellEditor(receiptTable);
		}

		return receiptTable;
	}

	/***/
	private Vector<String> getColumnNames() {
		Vector<String> columnNames = new Vector<String>();
		columnNames.add(LanguageLoader.getString("No"));
		columnNames.add(LanguageLoader.getString("Date"));
		columnNames.add(LanguageLoader.getString("SubjectEntity"));
		columnNames.add(LanguageLoader.getString("Income"));
		columnNames.add(LanguageLoader.getString("Expense"));
		columnNames.add(LanguageLoader.getString("Currency"));
		columnNames.add(LanguageLoader.getString("Passbook"));
		columnNames.add(LanguageLoader.getString("Memo"));

		return columnNames;
	}

	/***/
	private void setCellEditor(JTable table) {
		// Date
		// TableColumn column2 = table.getColumnModel().getColumn(2);
		// // SubjectEntity
		// TableColumn columnSubject = table.getColumnModel().getColumn(2);
		// final JComboBox subjectComboBox = new JComboBox();
		// PassbookComboBoxModel subjectComboBoxModel = new
		// PassbookComboBoxModel();
		// subjectComboBox.setModel(subjectComboBoxModel);
		// subjectComboBoxModel.setData(new SubjectService()
		// .getParentAndChildrenListByFlag(Constant.EXPENSE_KBN));
		// columnSubject.setCellEditor(new DefaultCellEditor(subjectComboBox));
		// subjectComboBox.setRenderer(new SubjectListCellRender());
		// columnSubject.setHeaderRenderer(new DefaultTableCellRenderer(){
		// @Override
		// public Component getTableCellRendererComponent(JTable table, Object
		// value,
		// boolean isSelected, boolean hasFocus, int row, int column) {
		// super.getTableCellRendererComponent(table, value, isSelected,
		// hasFocus, row, column);
		//                          
		// return subjectComboBox;
		// }
		// });
		//
		// TableColumn columnPassbook = table.getColumnModel().getColumn(6);
		// JComboBox passbookComboBox = new JComboBox();
		// PassbookComboBoxModel2 passbookComboBoxModel = new
		// PassbookComboBoxModel2();
		// passbookComboBox.setModel(passbookComboBoxModel);
		// columnPassbook.setCellEditor(new
		// DefaultCellEditor(passbookComboBox));
		// passbookComboBox.setRenderer(new PassbookListCellRender());

		// memo
		TableColumn columnMemo = table.getColumnModel().getColumn(7);
		columnMemo.setCellRenderer(new MemoReceiptTableCellRenderer());

	}

	public void showData(CalendarUtils c) {
		((ReceiptTabelModel) getReceiptTable().getModel()).setData(getData(c
				.getBeginDay(), c.getEndDay()));

		if (dataFilterGroup.getSelection() != null) {
			dataFilterButton.setText(LanguageLoader.getString("Data_Filter")
					+ " [" + dataFilterGroup.getSelection().getActionCommand()
					+ "]");
		}
	}

	public Vector<Entity> getData(String beginDay, String endDay) {
		Vector<Entity> vect = new Vector<Entity>();
		ReceiptService receiptService = new ReceiptService();
		List list = receiptService.getReceiptFormList(beginDay, endDay);
		Iterator it = list.iterator();
		while (it.hasNext()) {
			vect.add((Entity) it.next());
		}
		return vect;
	}

	@Override
	public String getPageName() {
		// TODO Auto-generated method stub

		return LanguageLoader.getString("Receipt");
	}

	@Override
	public void disposePage() {
		// TODO Auto-generated method stub
		super.disposePage();
		thisCardPanel = null;
	}

	@Override
	public void update(IPassbookEvent event) {
		// TODO Auto-generated method stub

	}

	/**
	 * ReceiptTable
	 */
	class ReceiptTable extends PassbookTable implements MouseListener {

		/**
		 * serialVersionUID
		 */
		private static final long serialVersionUID = 1L;

		private JPopupMenu popup;

		public ReceiptTable() {
			super();
			initTable();
		}

		private void initTable() {
			this.setPreferredScrollableViewportSize(new Dimension(500, 70));
			this.setFillsViewportHeight(true);
			this.getSelectionModel().setSelectionMode(
					ListSelectionModel.SINGLE_SELECTION);
			this.addMouseListener(this);
			this.setAutoCreateRowSorter(true);

			createPopupMenu();
		}

		public void createPopupMenu() {
			JMenuItem menuItem;

			// Create the popup menu.
			AbstractAction action;

			popup = new JPopupMenu();

			menuItem = new JMenuItem();
			action = (AbstractAction) ActionManager
					.getAction(ReceiptCopyAction.class);
			action.putValue("PassbookTable", this);
			menuItem.setAction(action);
			popup.add(menuItem);

			menuItem = new JMenuItem(LanguageLoader.getString("Paste"));
			action = (AbstractAction) ActionManager
					.getAction(ReceiptPasteAction.class);
			action.putValue("PassbookTable", this);
			menuItem.setAction(action);
			popup.add(menuItem);

			popup.add(new JSeparator());
			menuItem = new JMenuItem(ActionManager
					.getAction(ShowAddReceiptAction.class));
			popup.add(menuItem);

			menuItem = new JMenuItem(ActionManager
					.getAction(ShowModifyReceiptAction.class));
			popup.add(menuItem);

			menuItem = new JMenuItem(ActionManager
					.getAction(ShowDeleteReceiptAction.class));
			popup.add(menuItem);

		}

		@Override
		public void valueChanged(ListSelectionEvent e) {
			// Must invoke the super's method!
			super.valueChanged(e);

			if (this.getSelectedRow() != -1) {
				ActionManager.getAction(ShowModifyReceiptAction.class)
						.setEnabled(true);
				ActionManager.getAction(ShowDeleteReceiptAction.class)
						.setEnabled(true);
				ActionManager.getAction(ReceiptCopyAction.class).setEnabled(
						true);
			} else {
				ActionManager.getAction(ShowModifyReceiptAction.class)
						.setEnabled(false);
				ActionManager.getAction(ShowDeleteReceiptAction.class)
						.setEnabled(false);
				ActionManager.getAction(ReceiptCopyAction.class).setEnabled(
						false);
				// ActionManager.getAction(ReceiptPasteAction.class).setEnabled(
				// false);
			}
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			int button = e.getButton();
			int clickCount = e.getClickCount();
			int pointRow = this.rowAtPoint(e.getPoint());

			// row is selected.
			// modify
			if (pointRow != -1) {
				if (button == Constant.LEFT_CLICK
						&& clickCount == Constant.DOUBLE_CLICK) {
					modifyButton.doClick();
				}
			}

			// When cursor is out of table rows's view Area,double click.
			// add
			if (pointRow == -1) {
				if (button == Constant.LEFT_CLICK
						&& clickCount == Constant.DOUBLE_CLICK) {
					addButton.doClick();
				}
			}

		}

		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub
			showPopup(e);
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub
			showPopup(e);
		}

		private void showPopup(MouseEvent e) {
			int button = e.getButton();
			int pointRow = this.rowAtPoint(e.getPoint());

			// Right click, select row.
			if (button == Constant.RIGHT_CLICK && pointRow != -1) {
				this.clearSelection();
				this.addRowSelectionInterval(pointRow, pointRow);
			}

			if (e.isPopupTrigger()) {
				popup.show(e.getComponent(), e.getX(), e.getY());
			}
		}

	}

}
